﻿using System.ComponentModel.Composition;
using Cubicle.Core.Interfaces;
using Cubicle.Core.Repository.HandleParsers;

namespace Cubicle.Core.Processors.Invoke
{
    [Export("Cubicle.Processors.Invoke.TouchAndStoreProcessor", typeof(IProcessor<InstructionRequest>))]
    [ExportMetadata("Name", "TouchAndStoreProcessor")]
    [ExportMetadata("Description", "Saves results to the repository and returns the handle. If the user " +
                    "provides and empty key, results will not be stored but returned as is. " +
                    "If results are null, the handle of the target object will be touched and returned.")]
    public class TouchAndStoreProcessor : InstructionRequestProcessor
    {
        #region Overrides of ConditionalProcessor<InstructionRequest>

        [Import]
        private IRepository _repo;

        public TouchAndStoreProcessor() : base(RequestType.Completed) { }

        public override InstructionRequest ConditionalProcess(InstructionRequest request)
        {
            var instruction = request.Inst;

            // If the result is null, return the handle of the instruction
            if (request.Result() == null)
            {
                var handle = instruction.Handle;
                var robj = _repo.GetRObject(handle);
                if (robj == null)
                    return request;

                request.Result(robj.Parser is ExcelHandleParserNull || robj.Parser is ExcelHandleParserDefault
                    ? _repo.Rename(handle, robj.Key)
                    : instruction.Handle);
                return request;
            }

            // If the key is null, return the result rather than the handle
            request.Result(instruction.Key == null
                ? request.Result()
                : _repo.Set(instruction.Key, request.Result()));
            return request;
        }

        #endregion
    }
}
